﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

// 中间部分

namespace UFrame
{
    public class EffectPlayerInfo
    {
        public SkillEffectData data;
        public float playTime;
    }

    public class EffectListWindow : SkillSecondWindow
    {
        public SkillEffectInfo selectInfo = null;
        private string animationName = string.Empty;

        private LongTimeCounter counter;

        private List<string> animationNameList = null;

        private List<EffectPlayerInfo> needCreateData = new List<EffectPlayerInfo>();

        private Dictionary<SkillEffectData, AutoSetParticlePlayer> castEffectPlayerList =
            new Dictionary<SkillEffectData, AutoSetParticlePlayer>();

        private AutoSetParticlePlayer keepEffectPlayer = null;
        List<AutoSetParticlePlayer> hitEffectPlayerList = new List<AutoSetParticlePlayer>();

        private Dictionary<SkillEffectData, AutoSetParticlePlayer> moveHitEffectPlayerList =
            new Dictionary<SkillEffectData, AutoSetParticlePlayer>();

        private string[] hitTypeText = { "无", "怪物", "怪物和玩家" };
        private string[] hitPointType = { "无", "击退点" };
        private string[] hitPointType2 = { "无", "击退点", "扩散点" };

        private string[] playerSkillTypeText = { "可操控范围技能", "不可操控范围技能", "自身技能", "目标锁定", "位移技能" };
        private string[] attackRangeTypeText = { "", "自身扇形", "自身矩形", "目标圆形" };
        private string[] attackRangeTypeText2 = { "", "自身扇形", "自身矩形", "自身圆形" };

        private string[] attackTargetTypeText = { "敌对", "友军", "友军或自身" };


        private float maxTime = 0f;
        private float slider = 0f; // 滑动条
        private float curPlayTime = 0f;

        private float animationTime = 0f;

        private int index = 0;

        private float animationControlPer = 0f;


        private float playEffectStartTime;

        // public bool isDebugMode = true; // 带调试的模式
        public EffectListWindow(EffectEditor t, float x, float y, float width, float height) : base(t, x, y, width,
            height)
        {

        }

        public override void OnEditorEvent(IEditorEvent e)
        {
            switch ((SkillEffectEventEnum)e.GetEventID())
            {
                case SkillEffectEventEnum.SkillSelected:
                    {
                        /*string index = (string)e.GetEventData();
                        SkillEffectInfo info = null;
                        if (root.skillData.m_data.TryGetValue(index, out info))
                        {
                            m_selectInfo = info;

                            foreach (var v in  SkillDefManagerInstance.instance.data)
                            {                              
                                if (v.Value.m_highEffectConfigID == info.m_name)
                                {
                                    m_def = v.Value;
                                    break;
                                }
                            }
                            var list = m_root.m_meshPlayer.GetSkillAnimationNames();
                            m_index = 0;
                            m_animationNameList = new List<string> { " " };
                            m_animationNameList.AddRange(list);
                            if (m_selectInfo.m_skillAnimationID != 0)
                            {
                                int a = m_selectInfo.m_skillAnimationID % 10;
                                int b = m_selectInfo.m_skillAnimationID / 10;
                                m_animationName = string.Format("skill_{0}_{1}", b.ToString("00"), a.ToString("00"));
                                m_index = m_animationNameList.FindIndex(0,(x) => x == m_animationName);
                                m_root.m_meshPlayer.SetRecondAnimationClip(m_animationNameList[m_index]);
                                m_animationTime = m_selectInfo.m_skillAnimationLength;
                            }
                            else
                            {
                                m_animationName = string.Empty;
                            }
                        }
                        else
                        {
                            m_selectInfo = null;
                        }           */

                        root.effectInfoWindow.Clear();
                        Release();
                        GUI.FocusControl("");
                        break;
                    }
                case SkillEffectEventEnum.SkillRemove:
                    {
                        string index = (string)e.GetEventData();
                        if (selectInfo.name == index)
                        {
                            selectInfo = null;
                            root.effectInfoWindow.Clear();
                            // m_root.m_cameraInfoWindow.Clear();
                            Release();
                        }

                        break;
                    }
                case SkillEffectEventEnum.ChangeObj:
                    {
                        selectInfo = null;
                        root.effectInfoWindow.Clear();
                        // m_root.m_cameraInfoWindow.Clear();
                        Release();
                        break;
                    }
            }
        }

        public void Release()
        {

            foreach (var v in castEffectPlayerList)
            {
                v.Value.Release();
            }

            castEffectPlayerList.Clear();
            if (keepEffectPlayer != null)
            {
                keepEffectPlayer.Release();
                keepEffectPlayer = null;
            }

            foreach (var v in hitEffectPlayerList)
            {
                v.Release();
            }

            hitEffectPlayerList.Clear();

            foreach (var v in moveHitEffectPlayerList)
            {
                v.Value.Release();
            }

            moveHitEffectPlayerList.Clear();
            root.isPlaying = false;
            animationControlPer = 0f;
        }

        protected IEnumerator DelayPlay(AudioSource sfxPlayer, string sfxName, float delay)
        {
            yield return new WaitForSecondsRealtime(delay);
            string fullPath = $"Assets/Res/Sound/{sfxName}.mp3";
            var clip = AssetDatabase.LoadAssetAtPath<AudioClip>(fullPath);
            sfxPlayer.PlayOneShot(clip);
        }

        protected void PlayAudioclip()
        {
            playEffectStartTime = Time.realtimeSinceStartup;

            var audioSource = GameObject.FindObjectOfType<AudioSource>();
            if (audioSource == null)
            {
                GameObject g = new GameObject();
                g.name = "SFXPlayer";
                audioSource = g.AddComponent<AudioSource>();
            }

            foreach (var effect in selectInfo.castEffectList)
            {
                if (!string.IsNullOrWhiteSpace(effect.sfxName))
                {
                    EditorCoroutineRunner.StartEditorCoroutine(DelayPlay(audioSource, effect.sfxName, effect.castTime));
                }
            }
        }

        protected override void Draw(int id)
        {
            if (selectInfo != null)
            {
                root.attackTarget.SetActive(true);
                maxTime = root.meshPlayer.GetLength();
                ///释放技能效果
                foreach (var v in castEffectPlayerList)
                {
                    if (!selectInfo.castEffectList.Contains(v.Key))
                    {
                        v.Value.Release();
                        castEffectPlayerList.Remove(v.Key);
                        break;
                    }

                    float length = 0f;

                    length = v.Key.castTime + v.Key.effectTimeLength;
                    maxTime = maxTime > length ? maxTime : length;
                }

                foreach (var v in selectInfo.castEffectList)
                {
                    if (!castEffectPlayerList.ContainsKey(v))
                    {
                        if (v.effectName == string.Empty)
                        {
                            continue;
                        }

                        AutoSetParticlePlayer player = new AutoSetParticlePlayer();
                        player.CreateNormalEffect(root, selectInfo, v);
                        player.SetLength(v.effectTimeLength);
                        castEffectPlayerList.Add(v, player);
                    }
                }

                ///
                ///击中效果
                if (selectInfo.hitEffect == null || selectInfo.hitEffect.effectName == string.Empty)
                {
                    if (hitEffectPlayerList.Count > 0)
                    {
                        foreach (var v in hitEffectPlayerList)
                        {
                            v.Release();
                        }

                        hitEffectPlayerList.Clear();
                    }
                }

                if (selectInfo.hitEffect != null && selectInfo.hitEffect.effectName != string.Empty)
                {
                    int listCount = hitEffectPlayerList.Count;
                    int hitCount = selectInfo.hitTimes.Count;
                    if (listCount > hitCount)
                    {
                        int offer = listCount - hitCount;
                        for (int i = 0; i < offer; i++)
                        {
                            hitEffectPlayerList[hitEffectPlayerList.Count - 1].Release();
                            hitEffectPlayerList.RemoveAt(hitEffectPlayerList.Count - 1);
                        }
                    }
                    else if (listCount < hitCount)
                    {
                        int offer = hitCount - listCount;
                        for (int i = 0; i < offer; i++)
                        {
                            AutoSetParticlePlayer player = new AutoSetParticlePlayer();
                            player.CreateHitEffect(root, selectInfo.hitEffect, 0f);
                            player.SetLength(selectInfo.hitEffect.effectTimeLength);
                            hitEffectPlayerList.Add(player);
                        }
                    }

                    for (int i = 0; i < selectInfo.hitTimes.Count; i++)
                    {
                        hitEffectPlayerList[i].SetStartTime(selectInfo.hitTimes[i]);
                    }

                    float overTime = selectInfo.hitEffect.castTime + selectInfo.hitEffect.effectTimeLength;
                    maxTime = maxTime > overTime ? maxTime : overTime;
                }

                foreach (var v in moveHitEffectPlayerList)
                {
                    if (!selectInfo.castEffectList.Contains(v.Key))
                    {
                        moveHitEffectPlayerList[v.Key].Release();
                        moveHitEffectPlayerList.Remove(v.Key);
                        break;
                    }

                    AutoSetParticlePlayer castPlayer = castEffectPlayerList[v.Key];
                    castPlayer.Update(v.Key.castTime);
                    float needTime = 0f;
                    if (v.Key.speed != 0)
                    {
                        needTime = Vector3.Distance(castPlayer.GetPos(), root.attackTarget.transform.position) / v.Key.speed;
                    }

                    float startTime = v.Key.castTime + needTime;
                    v.Value.SetStartTime(startTime);
                    float overTime = startTime + v.Value.GetLength();
                    maxTime = maxTime > overTime ? maxTime : overTime;
                }


                ///持续性技能效果
                if (selectInfo.keepEffect == null || selectInfo.keepEffect.effectName == string.Empty)
                {
                    if (keepEffectPlayer != null)
                    {
                        keepEffectPlayer.Release();
                        keepEffectPlayer = null;
                    }
                }

                if (selectInfo.keepEffect != null && selectInfo.keepEffect.effectName != string.Empty)
                {
                    float length = selectInfo.keepEffect.castTime + selectInfo.keepEffect.effectTimeLength;
                    maxTime = maxTime > length ? maxTime : length;
                    if (keepEffectPlayer == null)
                    {
                        keepEffectPlayer = new AutoSetParticlePlayer();
                        keepEffectPlayer.CreateNormalEffect(root, selectInfo, selectInfo.keepEffect);
                        keepEffectPlayer.SetLength(maxTime + 1);
                    }
                }


                ///绘制界面
                GUILayout.BeginVertical();


                GUILayout.Label("选择使用的技能动作");
                EditorGUI.BeginChangeCheck();
                this.index = EditorGUILayout.Popup(this.index, animationNameList.ToArray());
                if (EditorGUI.EndChangeCheck())
                {
                    root.meshPlayer.SetRecondAnimationClip(animationNameList[this.index]);
                    if (this.index == 0)
                    {
                        //                        EditorUtility.DisplayDialog("")
                    }
                    else
                    {
                        string[] key = { "_" };
                        string[] strs = animationNameList[this.index].Split(key, StringSplitOptions.None);
                        if (strs.Length == 3)
                        {
                            selectInfo.skillAnimationID = int.Parse(strs[1]) * 10 + int.Parse(strs[2]);
                        }
                    }
                }


                GUILayout.BeginHorizontal();
                selectInfo.skillAnimationLength = root.meshPlayer.GetLength();
                GUILayout.Label("动作时长" + selectInfo.skillAnimationLength);

                GUILayout.EndHorizontal();
                selectInfo.skillComboTime = EditorGUILayout.FloatField("连击时间点", selectInfo.skillComboTime);

                GUILayout.BeginHorizontal();

                GUILayout.Label("动画时间" + animationControlPer * maxTime);
                EditorGUI.BeginChangeCheck();
                animationControlPer =
                    GUI.HorizontalScrollbar(new Rect(140, 95, 160, 15), animationControlPer, 0, 0, 1);

                if (EditorGUI.EndChangeCheck())
                {
                    root.isPlaying = false;
                }

                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("Play"))
                {
                    Release();
                    animationControlPer = 0f;
                    root.meshPlayer.TimeChange(0f);

                    root.isPlaying = true;
                    counter = new LongTimeCounter();
                    needCreateData.Clear();

                    // 尝试播放音效
                    PlayAudioclip();

                    maxTime = root.meshPlayer.GetLength();
                    bool isFindMoveType = false;
                    foreach (var effectData in needCreateData)
                    {
                        float time = 0f;
                        if (effectData.data.type == 2)
                        {
                            isFindMoveType = true;
                            float dis = Vector3.Distance(root.attackTarget.transform.position,
                                root.createdObject.transform.position);

                            float hittime = 0f;

                            if (selectInfo.hitEffect != null)
                            {
                                hittime = selectInfo.hitEffect.effectTimeLength;
                            }

                            time = effectData.data.castTime + dis / effectData.data.speed + hittime;
                        }
                        else
                        {
                            time = effectData.data.castTime + effectData.data.effectTimeLength;
                        }

                        if (maxTime < time)
                        {
                            maxTime = time;
                        }

                        if (effectData.data.type != 1)
                        {
                            root.attackTarget.SetActive(true);
                        }
                    }

                    animationTime = root.meshPlayer.GetLength();
                    ///创建击中效果
                    if (!isFindMoveType)
                    {
                        if (selectInfo.hitEffect != null && selectInfo.hitEffect.effectName != string.Empty)
                        {
                            foreach (float f in selectInfo.hitTimes)
                            {

                                float t = f + selectInfo.hitEffect.effectTimeLength;
                                if (t > maxTime)
                                {
                                    maxTime = t;
                                }
                            }
                        }
                    }

                    if (selectInfo.keepEffect != null && selectInfo.keepEffect.effectName != string.Empty)
                    {
                        //m_needCreateData.Add(new EffectPlayerInfo() { m_data = m_selectInfo.m_keepEffect, m_playTime = m_selectInfo.m_keepEffect.m_castTime });
                        float t = selectInfo.keepEffect.castTime + selectInfo.keepEffect.effectTimeLength;
                        if (t > maxTime)
                        {
                            maxTime = t;
                        }
                    }

                    root.createdObject.transform.position = Vector3.zero;

                    foreach (var effectPlayer in root.effectPlayer)
                    {
                        effectPlayer.Release();
                    }

                    root.effectPlayer.Clear();
                }

                if (GUILayout.Button("Stop"))
                {
                    root.isPlaying = false;
                }

                GUILayout.EndHorizontal();
                if (SkillEffectControlWindow.currentSelectPage == 1 || SkillEffectControlWindow.currentSelectPage == 3)
                {
                    GUILayout.BeginArea(new Rect(0, 135, 300, 80));
                    GUILayout.Label("位移部分配置");
                    if (!selectInfo.canMove)
                    {
                        if (GUILayout.Button("创建移动动画数据"))
                        {
                            if (EditorUtility.DisplayDialog("", "是否添加技能位移动画", "添加", "不用"))
                            {
                                selectInfo.curve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(1, 1));
                                selectInfo.skillMoveDis = 1f;
                                selectInfo.canMove = true;
                                return;
                            }
                        }

                        root.attackTarget.transform.position = new Vector3(0, 0, 5);
                    }
                    else
                    {
                        GUILayout.BeginHorizontal();
                        if (GUILayout.Button("删除"))
                        {
                            selectInfo.curve = null;
                            selectInfo.skillMoveDis = 0f;
                            selectInfo.canMove = false;
                        }

                        GUILayout.Label("位移距离");
                        selectInfo.skillMoveDis = EditorGUILayout.FloatField(selectInfo.skillMoveDis);
                        selectInfo.targetMove = GUILayout.Toggle(selectInfo.targetMove, "是否考虑目标");
                        root.attackTarget.transform.position = new Vector3(0, 0, selectInfo.skillMoveDis + 2);

                        GUILayout.EndHorizontal();
                        selectInfo.curve = EditorGUI.CurveField(new Rect(0, 40, 300, 40), selectInfo.curve);
                    }

                    GUILayout.EndArea();

                    // 技能类型
                    GUILayout.BeginArea(new Rect(0, 220, 300, 130));
                    GUILayout.Label("---------技能类型----------");
                    GUILayout.BeginHorizontal(); // 判定延迟
                    GUILayout.Label("判定延时");
                    selectInfo.penaltyTime = EditorGUILayout.FloatField(Math.Max(0f, selectInfo.penaltyTime));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal(); // 前摇
                    GUILayout.Label("前摇时长");
                    selectInfo.preSkillTime = EditorGUILayout.FloatField(Math.Max(0f, selectInfo.preSkillTime));
                    if (selectInfo.preSkillTime > 0f)
                    {
                        GUILayout.Label("前摇动作");
                        selectInfo.preSkillIndex = EditorGUILayout.Popup(selectInfo.preSkillIndex,
                            animationNameList.ToArray());
                        selectInfo.preSkillName = animationNameList[selectInfo.preSkillIndex];
                    }

                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal(); // 寻怪距离
                    GUILayout.Label("寻怪距离（自动获取与技能距离的较大值）");
                    selectInfo.findTargetDist =
                        EditorGUILayout.FloatField(Math.Max(0f, selectInfo.findTargetDist));
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("操作类型");
                    selectInfo.playerSkillType =
                        EditorGUILayout.Popup(selectInfo.playerSkillType, playerSkillTypeText);
                    GUILayout.EndHorizontal();
                    if (selectInfo.playerSkillType == 0) // 可控制范围的
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("目标类型");
                        selectInfo.attackTargetType =
                            EditorGUILayout.Popup(selectInfo.attackTargetType, attackTargetTypeText);
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Label("形状");
                        selectInfo.attackRangeType =
                            EditorGUILayout.Popup(Mathf.Max(selectInfo.attackRangeType, 1), attackRangeTypeText);
                        if (selectInfo.attackRangeType == 1) // 扇形
                        {
                            GUILayout.Label("角度");
                            selectInfo.attackCastDist = EditorGUILayout.FloatField(selectInfo.attackCastDist);
                            GUILayout.Label("距离");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        if (selectInfo.attackRangeType == 2) // 矩形
                        {
                            GUILayout.Label("宽度");
                            selectInfo.attackCastDist = EditorGUILayout.FloatField(selectInfo.attackCastDist);
                            GUILayout.Label("长度");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        if (selectInfo.attackRangeType == 3) // 圆形
                        {
                            GUILayout.Label("施放距离");
                            selectInfo.attackCastDist = EditorGUILayout.FloatField(selectInfo.attackCastDist);
                            GUILayout.Label("打击半径");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        GUILayout.EndHorizontal();
                    }

                    if (selectInfo.playerSkillType == 1) // 不可控制范围的
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("目标类型");
                        selectInfo.attackTargetType =
                            EditorGUILayout.Popup(selectInfo.attackTargetType, attackTargetTypeText);
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Label("形状");
                        selectInfo.attackRangeType =
                            EditorGUILayout.Popup(Mathf.Max(selectInfo.attackRangeType, 1), attackRangeTypeText2);
                        if (selectInfo.attackRangeType == 1) // 扇形
                        {
                            GUILayout.Label("角度");
                            selectInfo.attackCastDist = EditorGUILayout.FloatField(selectInfo.attackCastDist);
                            GUILayout.Label("距离");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        if (selectInfo.attackRangeType == 2) // 矩形
                        {
                            GUILayout.Label("宽度");
                            selectInfo.attackCastDist = EditorGUILayout.FloatField(selectInfo.attackCastDist);
                            GUILayout.Label("长度");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        if (selectInfo.attackRangeType == 3) // 圆形
                        {
                            selectInfo.attackCastDist = 0f;
                            GUILayout.Label("打击半径");
                            selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        }

                        GUILayout.EndHorizontal();
                    }

                    if (selectInfo.playerSkillType == 2) // 自身
                    {

                    }

                    if (selectInfo.playerSkillType == 3) // 锁定目标
                    {
                        selectInfo.attackRangeType = 0;

                        GUILayout.BeginHorizontal();
                        GUILayout.Label("目标类型");
                        selectInfo.attackTargetType =
                            EditorGUILayout.Popup(selectInfo.attackTargetType, attackTargetTypeText);
                        GUILayout.Label("施放距离");
                        selectInfo.attackRange = EditorGUILayout.FloatField(selectInfo.attackRange);
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        GUILayout.Label("命中后扩散");
                        selectInfo.isImpect = EditorGUILayout.Toggle(selectInfo.isImpect);

                        if (selectInfo.isImpect) // 如果扩散，设置扩散距离
                        {
                            GUILayout.Label("扩散半径");
                            selectInfo.impactRange = EditorGUILayout.FloatField(selectInfo.impactRange);
                        }

                        GUILayout.EndHorizontal();
                    }
                    else if (selectInfo.playerSkillType == 4) // 位移技能
                    {
                    }
                    else
                    {
                        selectInfo.isImpect = false;
                    }

                    GUILayout.EndArea();


                    // 击退部分
                    GUILayout.BeginArea(new Rect(0, 350, 300, 230));
                    GUILayout.Label("---------伤害点类型----------");
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("击退类型");
                    selectInfo.hitBackType = EditorGUILayout.Popup(selectInfo.hitBackType, hitTypeText);
                    GUILayout.EndHorizontal();
                    if (selectInfo.hitBackType != 0)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("击退距离");
                        selectInfo.hitBackDis = EditorGUILayout.FloatField(selectInfo.hitBackDis);
                        GUILayout.Label("时长");
                        selectInfo.hitBackTime = EditorGUILayout.FloatField(selectInfo.hitBackTime);
                        GUILayout.EndHorizontal();
                    }

                    GUILayout.Label("伤害时间点");
                    if (GUILayout.Button("添加时间点"))
                    {
                        selectInfo.hitTimes.Add(0.2f);
                    }

                    if (selectInfo.hitDeadEffectType.Count == 0)
                    {
                        for (int i = 0; i < selectInfo.hitTimes.Count; i++)
                        {
                            selectInfo.hitDeadEffectType.Add(0);
                        }
                    }

                    for (int i = 0; i < selectInfo.hitTimes.Count; i++)
                    {
                        GUILayout.BeginHorizontal();
                        selectInfo.hitTimes[i] = EditorGUILayout.FloatField("时间", selectInfo.hitTimes[i]);

                        if (selectInfo.hitDeadEffectType.Count < i + 1)
                        {
                            selectInfo.hitDeadEffectType.Add(1);
                        }

                        if (!selectInfo.isImpect)
                        {
                            selectInfo.hitDeadEffectType[i] = Mathf.Min(1, selectInfo.hitDeadEffectType[i]);
                            selectInfo.hitDeadEffectType[i] =
                                EditorGUILayout.Popup(Mathf.Min(1, selectInfo.hitDeadEffectType[i]),
                                    hitPointType);
                        }
                        else
                        {
                            selectInfo.hitDeadEffectType[i] =
                                EditorGUILayout.Popup(selectInfo.hitDeadEffectType[i], hitPointType2);
                        }

                        if (GUILayout.Button("删除"))
                        {
                            selectInfo.hitTimes.RemoveAt(i);
                            selectInfo.hitDeadEffectType.RemoveAt(i);
                            return;
                        }

                        GUILayout.EndHorizontal();
                    }

                    GUILayout.EndArea();
                }

                float y = (SkillEffectControlWindow.currentSelectPage == 1 ||
                           SkillEffectControlWindow.currentSelectPage == 3)
                    ? 580f
                    : 135f;

                if (SkillEffectControlWindow.currentSelectPage == 1 || SkillEffectControlWindow.currentSelectPage == 3)
                {
                    slider = GUI.VerticalSlider(new Rect(288f, 580f, 10f, 400f), slider, 0f, 1f);
                }

                GUILayout.BeginArea(new Rect(0, y, 290f, 1500f));

                GUILayout.BeginArea(new Rect(0, slider * -1080f, 290f, 1500f)); // for slider

                // 怪物旋转
                if (SkillEffectControlWindow.currentSelectPage == 2)
                {
                    GUILayout.Label("---------怪物朝向----------");
                    selectInfo.isMonsterDontRotate =
                        GUILayout.Toggle(selectInfo.isMonsterDontRotate, "怪物释放技能时不改变朝向");
                }

                GUILayout.Label("---------技能特效----------");
                GUILayout.Label("施法特效");
                if (GUILayout.Button(" 添加新特效 "))
                {
                    SkillEffectData data = new SkillEffectData();
                    data.effectType = SkillEffectType.Cast;
                    selectInfo.castEffectList.Add(data);
                }

                foreach (var v in selectInfo.castEffectList)
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(v.effectName))
                    {
                        SkillEffectEvent ev = new SkillEffectEvent()
                        {
                            eventT = SkillEffectEventEnum.EffectSelected,
                            obj = v,
                        };
                        root.OnEvent(ev);
                    }

                    if (GUILayout.Button("删除"))
                    {
                        selectInfo.castEffectList.Remove(v);
                        if (root.effectInfoWindow.selectEffectData == v)
                        {
                            root.effectInfoWindow.Clear();
                        }

                        return;
                    }

                    GUILayout.EndHorizontal();
                }

                // 命中特效
                GUILayout.Label("命中特效");
                if (selectInfo.hitEffect == null)
                {
                    if (GUILayout.Button("创建命中特效"))
                    {
                        selectInfo.hitEffect = new SkillEffectData();
                        selectInfo.hitEffect.effectType = SkillEffectType.Hit;
                        return;
                    }
                }
                else
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(selectInfo.hitEffect.effectName))
                    {
                        selectInfo.hitEffect.effectType = SkillEffectType.Hit;
                        SkillEffectEvent ev = new SkillEffectEvent()
                        {
                            eventT = SkillEffectEventEnum.EffectSelected,
                            obj = selectInfo.hitEffect,
                        };

                        root.OnEvent(ev);

                    }

                    if (GUILayout.Button("删除"))
                    {
                        if (root.effectInfoWindow.selectEffectData == selectInfo.hitEffect)
                        {
                            root.effectInfoWindow.Clear();
                        }

                        selectInfo.hitEffect = new SkillEffectData();

                        return;
                    }

                    GUILayout.EndHorizontal();
                }

                // 持续类特效
                GUILayout.Label("持续类特效（与服务器同步）");
                if (selectInfo.keepEffect == null)
                {
                    if (GUILayout.Button("创建持续类特效"))
                    {
                        selectInfo.keepEffect = new SkillEffectData();
                        selectInfo.keepEffect.effectType = SkillEffectType.Keep;
                        return;
                    }
                }
                else
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(selectInfo.keepEffect.effectName))
                    {
                        selectInfo.keepEffect.effectType = SkillEffectType.Keep;
                        SkillEffectEvent ev = new SkillEffectEvent()
                        {
                            eventT = SkillEffectEventEnum.EffectSelected,
                            obj = selectInfo.keepEffect,
                        };
                        root.OnEvent(ev);
                    }

                    if (GUILayout.Button("删除"))
                    {
                        if (root.effectInfoWindow.selectEffectData == selectInfo.keepEffect)
                        {
                            // m_root.m_cameraInfoWindow.Clear();
                            root.effectInfoWindow.Clear();
                        }

                        selectInfo.keepEffect = new SkillEffectData();
                        return;
                    }

                    GUILayout.EndHorizontal();
                }

                // 前摇特效
                if (selectInfo.preSkillTime > 0f)
                {
                    GUILayout.Label("前摇特效（无预览）");
                    if (GUILayout.Button(" 添加新特效 "))
                    {
                        SkillEffectData data = new SkillEffectData();
                        data.effectType = SkillEffectType.PreSkill;
                        selectInfo.preSkillEffectList.Add(data);
                    }

                    foreach (var v in selectInfo.preSkillEffectList)
                    {
                        GUILayout.BeginHorizontal();
                        if (GUILayout.Button(v.effectName))
                        {
                            SkillEffectEvent ev = new SkillEffectEvent()
                            {
                                eventT = SkillEffectEventEnum.EffectSelected,
                                obj = v,
                            };

                            root.OnEvent(ev);

                        }

                        if (GUILayout.Button("删除"))
                        {
                            selectInfo.preSkillEffectList.Remove(v);
                            if (root.effectInfoWindow.selectEffectData == v)
                            {
                                root.effectInfoWindow.Clear();
                            }

                            return;
                        }

                        GUILayout.EndHorizontal();
                    }
                }

                #region 相机震动

                // 相机震动
                GUILayout.Label("相机震动");
                if (GUILayout.Button("添加相机震动"))
                {
                    CameraShakeInfo info = new CameraShakeInfo();
                    selectInfo.cameraShakeInfoList.Add(info);
                }

                int index = 1;
                foreach (var v in selectInfo.cameraShakeInfoList)
                {
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button(string.Format("震动点 ({0}s)", v.delayTime)))
                    {
                        SkillEffectEvent e = new SkillEffectEvent()
                        {
                            eventT = SkillEffectEventEnum.CameraShakeSelected,
                            obj = v,
                        };
                        root.OnEvent(e);
                    }

                    if (GUILayout.Button("删除"))
                    {
                        selectInfo.cameraShakeInfoList.Remove(v);
                        if (root.effectInfoWindow.selectCameraData == v)
                        {
                            // m_root.m_cameraInfoWindow.Clear();
                            root.effectInfoWindow.Clear();
                        }

                        return;
                    }

                    GUILayout.EndHorizontal();
                }

                #endregion

                GUILayout.EndArea(); // for slider
                GUILayout.EndArea();
                GUILayout.EndVertical();
            }


            float playTime = 0f;
            if (root.isPlaying)
            {
                playTime = counter.GetPassTime();
            }
            else
            {
                playTime = animationControlPer * maxTime;
            }


            foreach (var v in castEffectPlayerList)
            {
                v.Value.Update(playTime);
            }

            if (keepEffectPlayer != null)
            {
                keepEffectPlayer.Update(playTime);
            }

            foreach (var v in hitEffectPlayerList)
            {
                v.Update(playTime);
            }

            foreach (var v in moveHitEffectPlayerList)
            {
                v.Value.Update(playTime);
            }

            if (root.meshPlayer != null)
            {
                root.meshPlayer.TimeChange(playTime);
            }

            float per = playTime / maxTime;

            if (selectInfo != null)
            {
                if (selectInfo.canMove && selectInfo.curve != null)
                {
                    float animationPer = playTime / animationTime;
                    if (animationPer <= 1f)
                    {
                        root.createdObject.transform.position = Vector3.Lerp(Vector3.zero,
                            root.attackTarget.transform.position + Vector3.back * 2,
                            selectInfo.curve.Evaluate(animationPer));
                    }
                }
            }

            if (per > 1)
            {
                root.isPlaying = false;
            }
        }


    }

    /// <summary>
    /// 粒子播放
    /// </summary>
    public class AutoSetParticlePlayer
    {
        public enum EditorParticlePlayerType
        {
            Cast,
            Hit,
        }

        public EditorParticlePlayerType type;
        private EditorParticlePlayer player;
        private EditorParticlePlayer hitPlayer;
        private SkillEffectInfo info;
        private SkillEffectData data;
        private string effectName = string.Empty;

        private EffectEditor root;

        public Vector3 GetPos()
        {
            return player.transform.position;
        }

        private void SetEffectName(string name)
        {
            if (!string.Equals(effectName, name))
            {
                effectName = name;
                GameObject go = data.EditorGetObject();

                if (go == null)
                {
                    return;
                }

                player.SetParticleGameObject(GameObject.Instantiate(go));
            }
        }

        private void CheckType()
        {
            if (data.effectType == SkillEffectType.Cast)
            {
                if (data.type == 0 && info.playerSkillType == 0) // 可指定范围
                {
                    player.SetTarget(root.attackTarget.transform, 0, data.castTime);
                }

                if (data.type == 0 && info.playerSkillType == 1) // 不可指定
                {
                    player.SetTarget(null, 0, data.castTime);
                }

                if (data.type == 1)
                {
                    player.SetTarget(root.attackTarget.transform, 0f, data.castTime);
                }
            }

            if (data.effectType == SkillEffectType.Hit)
            {
                player.SetTarget(root.attackTarget.transform, 0, data.castTime);
            }
        }

        public float GetLength()
        {
            return player.GetLength();
        }

        private void UpdatePos(float time = 0f)
        {
            Transform bone = null;
            if (player.transform == null)
            {
                return;
            }

            #region  播放施法特效

            if (type == EditorParticlePlayerType.Cast)
            {
                if (data.type == 1) // 追踪型
                {
                    if (!string.IsNullOrEmpty(data.boneName) && root.effectBones.ContainsKey(data.boneName))
                    {
                        if (data.isBind && data.isPosition)
                        {
                            root.meshPlayer.TimeChange(time);
                        }
                        else
                        {
                            root.meshPlayer.TimeChange(data.castTime);
                        }

                        bone = root.effectBones[data.boneName];
                    }
                    else
                    {
                        bone = root.createdObject.transform;
                    }

                    float t = data.curveCloseto.Evaluate(
                        (time - data.castTime) / Mathf.Max(0.001f, data.effectTimeLength));

                    Vector3 startPos = bone.position + root.createdObject.transform.rotation * data.offer;
                    Vector3 endPos = root.attackTarget.transform.position + Vector3.up;
                    Vector3 pos = Vector3.Lerp(startPos, endPos, t);
                    Vector3 lastPos = Vector3.Lerp(startPos, endPos, t - 0.03f);

                    if (data.motionOffsetX != 0)
                    {
                        pos += Vector3.right * data.curveMotionOffsetX.Evaluate(t) * data.motionOffsetX;
                        lastPos += Vector3.right * data.curveMotionOffsetX.Evaluate(t - 0.03f) *
                                   data.motionOffsetX;
                    }

                    if (data.motionOffsetY != 0)
                    {
                        pos += Vector3.up * data.curveMotionOffsetY.Evaluate(t) * data.motionOffsetY;
                        lastPos += Vector3.up * data.curveMotionOffsetY.Evaluate(t - 0.03f) *
                                   data.motionOffsetY;
                    }

                    // 设定位置
                    player.SetTransform(bone, data.offer, data.rotation, false, false);
                    player.SetPos(pos);

                    Vector3 rotate = pos - lastPos;
                    if (rotate.Equals(Vector3.zero))
                    {
                        player.transform.forward = data.rotation * root.createdObject.transform.forward;
                    }
                    else
                    {
                        player.transform.forward = data.rotation * rotate.normalized;
                    }
                }

                if (data.type == 0 /* && m_info.m_playerSkillType == 0 */) // 可控制的固定型
                {
                    if (!string.IsNullOrEmpty(data.boneName))
                    {
                        if (root.effectBones.ContainsKey(data.boneName))
                        {
                            if (data.isBind && data.isPosition)
                            {
                                root.meshPlayer.TimeChange(time);
                            }
                            else
                            {
                                root.meshPlayer.TimeChange(data.castTime);
                            }

                            bone = root.effectBones[data.boneName];
                        }
                        else
                        {
                            bone = root.createdObject.transform;
                        }
                    }
                    else
                    {
                        bone = root.createdObject.transform;
                    }

                    // 设定位置
                    if (data.isBind)
                    {
                        if (data.isPosition)
                        {
                            player.SetTransform(bone, data.offer, data.rotation, true, true);
                        }
                        else
                        {
                            player.SetTransform(bone, data.offer, data.rotation, true, false);
                            player.SetTransform(bone);
                            player.SetOffer(data.offer);
                            player.transform.localRotation = data.rotation;
                        }
                    }
                    else
                    {
                        player.SetTransform(bone, data.offer, data.rotation, false, false);
                        player.SetPos(bone.position + root.createdObject.transform.rotation * data.offer);
                        player.transform.localRotation = data.rotation;
                        // m_player.m_transform.forward = m_data.m_rotation * m_root.m_createdObject.transform.forward;
                    }
                }

                if (data.type == 2) // 地面型
                {
                    if (!string.IsNullOrEmpty(data.boneName))
                    {
                        if (root.targetBoneList.ContainsKey(data.boneName))
                        {
                            if (data.isBind && data.isPosition)
                            {
                                root.meshPlayer.TimeChange(time);
                            }
                            else
                            {
                                root.meshPlayer.TimeChange(data.castTime);
                            }

                            bone = root.targetBoneList[data.boneName];
                        }
                        else
                        {
                            bone = root.attackTarget.transform;
                        }
                    }
                    else
                    {
                        bone = root.attackTarget.transform;
                    }

                    player.SetTransform(bone, data.offer, data.rotation, false, false);
                    player.SetPos(bone.position + root.createdObject.transform.rotation * data.offer);
                    player.transform.forward = data.rotation * root.createdObject.transform.forward;
                }

                if (data.type == 3) // 运动型
                {
                    if (!string.IsNullOrEmpty(data.boneName) && root.effectBones.ContainsKey(data.boneName))
                    {
                        if (data.isBind && data.isPosition)
                        {
                            root.meshPlayer.TimeChange(time);
                        }
                        else
                        {
                            root.meshPlayer.TimeChange(data.castTime);
                        }

                        bone = root.effectBones[data.boneName];
                    }
                    else
                    {
                        bone = root.createdObject.transform;
                    }


                    float t = data.curveCloseto.Evaluate(
                        (time - data.castTime) / Mathf.Max(0.001f, data.effectTimeLength));

                    Vector3 startPos = bone.position + root.createdObject.transform.rotation * data.offer;
                    Vector3 endPos = startPos + Vector3.forward * data.motionDist;
                    Vector3 pos = Vector3.Lerp(startPos, endPos, t);
                    Vector3 lastPos = Vector3.Lerp(startPos, endPos, t - 0.03f);

                    if (data.motionOffsetX != 0)
                    {
                        pos += Vector3.right * data.curveMotionOffsetX.Evaluate(t) * data.motionOffsetX;
                        lastPos += Vector3.right * data.curveMotionOffsetX.Evaluate(t - 0.03f) *
                                   data.motionOffsetX;
                    }

                    if (data.motionOffsetY != 0)
                    {
                        pos += Vector3.up * data.curveMotionOffsetY.Evaluate(t) * data.motionOffsetY;
                        lastPos += Vector3.up * data.curveMotionOffsetY.Evaluate(t - 0.03f) *
                                   data.motionOffsetY;
                    }

                    pos += Vector3.forward * data.curveCloseto.Evaluate(t) * data.motionDist;
                    lastPos += Vector3.forward * data.curveCloseto.Evaluate(t - 0.03f) * data.motionDist;

                    // 设定位置
                    player.SetTransform(bone, data.offer, data.rotation, false, false);
                    player.SetPos(pos);

                    Vector3 rotate = pos - lastPos;
                    if (rotate.Equals(Vector3.zero))
                    {
                        player.transform.forward = data.rotation * root.createdObject.transform.forward;
                    }
                    else
                    {
                        player.transform.forward = data.rotation * rotate.normalized;
                    }
                }
            }

            #endregion

            if (type == EditorParticlePlayerType.Hit)
            {
                Vector3 pos;
                if (root.targetBoneList.ContainsKey("hit"))
                {
                    bone = root.targetBoneList["hit"];
                    pos = bone.position;
                }
                else
                {
                    bone = root.attackTarget.transform;
                    pos = bone.position + Vector3.up;
                }

                player.SetTransform(bone, data.offer, data.rotation, false, false);
                player.SetPos(pos);
                player.transform.forward = data.rotation * root.createdObject.transform.forward;
            }
        }

        public void Update(float time)
        {
            SetEffectName(data.effectName);
            CheckType();
            UpdatePos(time);
            if (type == EditorParticlePlayerType.Cast || type == EditorParticlePlayerType.Hit)
            {
                player.ChangeStartTime(data.castTime);
            }


            player.Update(time);
            player.TimeChange(time);
        }

        public void Release()
        {
            player.Release();
        }

        public void SetStartTime(float time)
        {
            player.ChangeStartTime(time);
        }

        public void SetLength(float time)
        {
            //m_player.SetLength(time);
        }

        public void CreateNormalEffect(EffectEditor root, SkillEffectInfo info, SkillEffectData data)
        {
            this.info = info;
            this.data = data;
            this.root = root;
            effectName = string.Empty;
            player = new EditorParticlePlayer();
            SetEffectName(this.data.effectName);
            UpdatePos();
            type = EditorParticlePlayerType.Cast;
            player.ChangeStartTime(data.castTime);
        }

        public void CreateHitEffect(EffectEditor root, SkillEffectData data, float time)
        {
            type = EditorParticlePlayerType.Hit;
            this.data = data;
            this.root = root;

            effectName = string.Empty;
            player = new EditorParticlePlayer();
            if (this.data != null)
            {
                SetEffectName(this.data.effectName);
            }

            UpdatePos();
            player.ChangeStartTime(data.castTime);
        }
    }
}